
#include <chrono>
#include <exceptdef.h>
#include <iostream>
#include <iterator.hpp>
#include <string.hpp>
#include <type_traits.hpp>
#include <type_traits>


// 测试类 A , 检测容器内存安全

class A {
	using T = int;

public:
	A() { }
	A( T v ) { _ptr = new T( v ); }
	A( const A& a ) {
		// TING_DEBUG("A(T)");
		if ( a._ptr != nullptr ) {
			_ptr = new T( *a._ptr );
		}
	}

	A( A&& other ) {
		// TING_DEBUG("A(A&& other)");
		delete _ptr;
		_ptr = other._ptr;
		other._ptr = nullptr;
	}

	void operator=( A other ) { swap( other ); }

	void swap( A& other ) { std::swap( other._ptr, _ptr ); }

	~A() {
		// TING_DEBUG("~A()");
		delete _ptr;
	}


	friend std::ostream& operator<<( std::ostream& os, const A& a ) {
		os << *a._ptr;
		return os;
	}

	bool operator==( const A& other ) { return *_ptr == *other._ptr; }

private:
	T* _ptr = nullptr;
};


// 针对容器 特化
template <typename T>
typename TingSTL::enable_if_t<TingSTL::has_iterator<T>::value, void>
testPrint( const T& container, const char* log = "" ) {
	std::cout << log;
	for ( auto& i : container )
		std::cout << i << ",";

	std::cout << std::endl;
}

// 针对 非容器进行特化
template <typename T>
typename TingSTL::enable_if<!TingSTL::has_iterator<T>::value, void>::type
testPrint( const T& value, const char* log = "" ) {
	std::cout << log << value << std::endl;
}

// 输出函数运行 运行时间信息
class RunTimerLogger {
private:
	TingSTL::string _log; // 要输出的日志
	std::chrono::time_point<std::chrono::high_resolution_clock> _startTime;

public:
	explicit RunTimerLogger( const char* log )
	    : _log( log ) {
		_startTime = std::chrono::high_resolution_clock::now();
	}

	~RunTimerLogger() {
		using namespace std::chrono;
		auto start = time_point_cast<microseconds>( _startTime )
		                 .time_since_epoch()
		                 .count();
		auto end = time_point_cast<microseconds>(
		               std::chrono::high_resolution_clock::now() )
		               .time_since_epoch()
		               .count();

		std::cout << "[" << _log << "] : "
		          << "run Millisecond: " << end - start << "\n";
	}
};
